package killgohorse.triangulo;

import killgohorse.FiguraGeometrica;
import killgohorse.FiguraGeometricaException;

/**
 *
 * @author Leo Antunes
 * @author Roberta Almeida
 */
public class Triangulo extends FiguraGeometrica {
    private int ladoA;
    private int ladoB;
    private int ladoC;

    public enum TipoTriangulo { Equilatero, Isosceles, Escaleno };

    public Triangulo(int ladoA, int ladoB, int ladoC) throws FiguraGeometricaException {
        verificarPreCondicoes(ladoA, ladoB, ladoC);
        this.ladoA = ladoA;
        this.ladoB = ladoB;
        this.ladoC = ladoC;
    }

    public int getLadoA() {
        return ladoA;
    }

    public void setLadoA(int ladoA) {
        this.ladoA = ladoA;
    }

    public int getLadoB() {
        return ladoB;
    }

    public void setLadoB(int ladoB) {
        this.ladoB = ladoB;
    }

    public int getLadoC() {
        return ladoC;
    }

    public void setLadoC(int ladoC) {
        this.ladoC = ladoC;
    }

    @Override
    public double area() {
        double semiPerim = (ladoA + ladoB + ladoC)/2.0; // semiPerim é o semi perimetro do triangulo
        return Math.sqrt(semiPerim * (semiPerim - ladoA) * (semiPerim - ladoB) * (semiPerim - ladoC));
    }

    @Override
    public double perimetro() {
        return ladoA + ladoB + ladoC;
    }

    public TipoTriangulo tipo() throws FiguraGeometricaException {
        verificarPreCondicoes(ladoA, ladoB, ladoC);

        if (isEquilatero(ladoA, ladoB, ladoC))
            return TipoTriangulo.Equilatero;
        else if (isEscaleno(ladoA, ladoB, ladoC))
            return TipoTriangulo.Escaleno;
        else if (isIsosceles(ladoA, ladoB, ladoC))
            return TipoTriangulo.Isosceles;
        else
            return null;
    } 

    private void verificarPreCondicoes(int ladoA, int ladoB, int ladoC) throws FiguraGeometricaException {
        preCond_ValorMaiorQueZero(ladoA, "Lado A");
        preCond_ValorMaiorQueZero(ladoB, "Lado B");
        preCond_ValorMaiorQueZero(ladoC, "Lado C");
        
        isTriangulo(ladoA, ladoB, ladoC);
        isTriangulo(ladoA, ladoC, ladoB);
        isTriangulo(ladoB, ladoC, ladoA);
    }

    private void isTriangulo(int ladoA, int ladoB, int ladoMaior)  throws FiguraGeometricaException {
        if ( (Math.abs(ladoA - ladoB) >= ladoMaior) ||
             (ladoMaior >= ladoA + ladoB) ){
            throw new FiguraGeometricaException("Triângulo inválido.");
        }
    }

    private boolean isIsosceles(int ladoA, int ladoB, int ladoC) {
        return  apenasDoisPrimeirosLadosIguais(ladoA, ladoB, ladoC) ||
                apenasDoisPrimeirosLadosIguais(ladoA, ladoC, ladoB) ||
                apenasDoisPrimeirosLadosIguais(ladoB, ladoC, ladoA);
    }

    private boolean isEquilatero(int ladoA, int ladoB, int ladoC) {
        return (ladoA == ladoB) && (ladoA == ladoC);
    }

    private boolean isEscaleno(int ladoA, int ladoB, int ladoC) {
        return ladoA != ladoB && ladoA != ladoC && ladoB != ladoC;
    }

    private boolean apenasDoisPrimeirosLadosIguais(int ladoA, int ladoB, int ladoC) {
        return (ladoA == ladoB && ladoA != ladoC);
    }
}